package hw.ats.news.activity.news;

import hw.ats.news.R;
import hw.ats.news.activity.DBAwareActivity;
import hw.ats.news.ds.NewsParser;
import hw.ats.news.model.News;
import hw.ats.news.ui.BottomTabHostProvider;
import hw.ats.news.ui.CommonUI;
import hw.ats.news.ui.NewsResourceHolder;
import hw.ats.news.util.App;
import hw.ats.news.util.DataLoader;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;

import com.humanwares.ui.asyncimage.ImageDisplayer;
import com.humanwares.ui.asyncimage.ImageReceivedCallback;
import com.humanwares.ui.asyncimage.ImageReceiver;
import com.humanwares.ui.tabbar.TabHost;
import com.tattermedia.allthataudio.audio.AudioPlayerDialogTool;
import com.tattermedia.allthataudio.audio.AudioPlayerManager;
import com.tattermedia.allthataudio.audio.CommonAudioPlayerStatusListener;
import com.tattermedia.allthataudio.audio.IAudioPlayerStatusListener;
import com.tattermedia.allthataudio.misc.DebugFlag;
import com.tattermedia.allthataudio.views.AudioPlayerProgressView;

public class SearchAct extends DBAwareActivity implements ImageReceivedCallback {
	private final static String TAG = "SearchAct";
	
	private ImageButton searchBtn = null;
	private EditText searchKeyword = null;
	private ListView listView = null;
	private List<News> items = new ArrayList<News>();
	private TabHost navbar = null;
	
	// audio status listener
	private IAudioPlayerStatusListener		mAudioStatusListener;
	
	private boolean thumbDisplay = false;
	
	/**
	 * 검색어
	 */
	private String keyword = null;
	
	/**
	 * 레코드 시작번호
	 */
	private int start = 0;
	
	/**
	 * 패치할 레코드 개수
	 */
	private int rows = App.ROW_PER_PAGE;
	
	/**
	 * 다음 패치할 데이터가 있을 경우 true
	 */
	private boolean hasNext = true;
	
	private int page = 1;
	
	private static int items_count = App.ITEMS_PER_PAGE;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
        thumbDisplay = pref.getBoolean("pref_list_thumb", true);
        
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        
        setContentView(R.layout.act_search);
        
        // 탭바 초기화
        navbar = CommonUI.renderTabBar(this, BottomTabHostProvider.TAB5);
        navbar.setVisibility(View.INVISIBLE);
        
		// 네비게이션바 제목
        CommonUI.renderAppTitle(this);
        
        // 좌측 네비게이션 버튼 = 이전화면 (키보드 숨김 추가)
        ImageButton leftImageButton = (ImageButton)findViewById(R.id.navbar_left);
        if (leftImageButton != null) {
        	leftImageButton.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 
					imm.hideSoftInputFromWindow(searchKeyword.getWindowToken(), 0);
					finish();
				}
			});
        }
        
		searchKeyword = (EditText)findViewById(R.id.search_keyword);
// 자동포커스 안되도록
//		searchKeyword.setFocusableInTouchMode(false);
//		searchKeyword.setOnTouchListener(new OnTouchListener() {
//			@Override
//			public boolean onTouch(View v, MotionEvent event) {
//				if (event.getAction() == MotionEvent.ACTION_DOWN &&
//					searchKeyword.getTag() == null) {
//					searchKeyword.setTag(Boolean.TRUE);
//					searchKeyword.setFocusableInTouchMode(true);
//				}
//				
//				return false;
//			}
//		});
		// 소프트키보드 완료 터치시 이벤트
		searchKeyword.setOnEditorActionListener(new OnEditorActionListener() {
			@Override
			public boolean onEditorAction(TextView v, int actionId,
					KeyEvent event) {
				if ((actionId == EditorInfo.IME_ACTION_DONE)
						|| (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) {
					search(searchKeyword.getText().toString());
				}
				return false;
			}
		});
		
		searchBtn = (ImageButton)findViewById(R.id.search_btn);
		searchBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				search(searchKeyword.getText().toString());
			}
		});
		
		listView = (ListView)findViewById(R.id.search_list);
		listView.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				News news = items.get(position);
				Intent intent = new Intent(SearchAct.this, ViewAct.class);
				intent.putExtra(App.INTENT_EXTRA_NEWS_UID, news.uid);
				intent.putExtra(App.INTENT_EXTRA_KEYWORD, keyword);
				intent.putExtra(App.INTENT_EXTRA_ACT_NAME, SearchAct.class.getName());
			    startActivity(intent);
			}
        });
		
		
        // add audio status listener
        mAudioStatusListener = new CommonAudioPlayerStatusListener(
        		(ImageButton)findViewById(R.id.audio_player_button_play), 
        		(ImageButton)findViewById(R.id.audio_player_button_repeat),
        		(ImageButton)findViewById(R.id.audio_player_button_prev),
        		(ImageButton)findViewById(R.id.audio_player_button_next),
        		(TextView)findViewById(R.id.audio_player_text_subject),
        		(TextView)findViewById(R.id.audio_player_text_time),
        		(AudioPlayerProgressView)findViewById(R.id.audio_player_progress_view));
        
        AudioPlayerManager.getManager().addAudioPlayerStatusListener(mAudioStatusListener);
		
    }
    
    @Override
	protected void onDestroy() {
		super.onDestroy();
		
		AudioPlayerManager.getManager().removeAudioPlayerStatusListener(mAudioStatusListener);
		
		if (DebugFlag.isLogEnabled()) Log.d(TAG, "onDestroy()");
		closeDatabase();
	}
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        int visibility = navbar.getVisibility();
        navbar.setVisibility(visibility == View.VISIBLE ? View.INVISIBLE : View.VISIBLE);
        return false;
    }
    
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event)  {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
//	    	Intent intent = new Intent(SearchAct.this, RecmdAct.class);
//	    	startActivity(intent);
//	    	finish();
//	    	overridePendingTransition(0, 0);
			InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 
			imm.hideSoftInputFromWindow(searchKeyword.getWindowToken(), 0);
			finish();
            return true;
        }

        return super.onKeyDown(keyCode, event);
    }
    
    /**
     * 이미지 로더
     */
	public void onImageReceived(ImageDisplayer displayer) {
		this.runOnUiThread(displayer);
	}
	
    public void search(String keyword) {
    	if (keyword == null || keyword.trim().length() == 0) {
			// 키보드 숨김
			InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 
			imm.hideSoftInputFromWindow(searchKeyword.getWindowToken(), 0);
			
    		Toast.makeText(this, "검색할 검색어를 입력하여 주십시오.", Toast.LENGTH_SHORT).show();
    		return;
    	}
    	
    	this.start = 0;
    	this.keyword = keyword.trim();
    	this.items.clear();
    	
    	new AsyncTask<String, Integer, Boolean>() {
    		private ProgressDialog progressDialog;
    		
    		@Override
    		protected void onPreExecute() {
    			super.onPreExecute();
    			
    			// 키보드 숨김
    			InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 
    			imm.hideSoftInputFromWindow(searchKeyword.getWindowToken(), 0);
    			
    	    	progressDialog = ProgressDialog.show(
    	        		SearchAct.this, App.APP_TITLE, "글을 검색하고 있습니다.", true, false);
    		}
    		
			@Override
			protected Boolean doInBackground(String... params) {
				loadData();
//				loadData_legacy();
				return true;
			}
			
			@Override
			protected void onProgressUpdate(Integer... progress) {
			}

			@Override
			protected void onPostExecute(Boolean result) {
		    	listView.setAdapter(new SearchAdapter(SearchAct.this));
				progressDialog.dismiss();
				if (items.size() == 0) {
					Toast.makeText(SearchAct.this, 
							"검색된 글이 없습니다.", Toast.LENGTH_SHORT).show();
				}
			}

			@Override
			protected void onCancelled() {
				super.onCancelled();
				progressDialog.dismiss();
			}
		}.execute();
    }

    private void loadData(){
    	hasNext = false;
    	NewsParser parser = new NewsParser();
    	Log.d("SearchAct", "searching entries");
    	try{
    		String encoded_keyword = URLEncoder.encode(keyword, "UTF-8");
    		List<News> newItems = parser.parse(App.NEWS_XML_URL + page + "&keyword=" + encoded_keyword);
    		for (int i = 0, len = newItems.size(); i < len; i++) {
    			News news = newItems.get(i);
				News dbNews = News.load(getReadableDatabase(), news.uid);
				
				if (dbNews == null) {
//					DataLoader.loadNewsBody(getDBHelper(), news, false);
					news.insert(getWritableDatabase());
					
				} else {
					news = dbNews;
				}
				
				items.add(news);
    				
    		}
    		if (newItems.size() == items_count ) 
    			this.hasNext = true;
    		else 
    			this.hasNext = false;
    		
    		if (newItems.size() == 0) {
    			loadData_legacy();
    		}
    		
    	}catch(UnsupportedEncodingException e ){
    		e.printStackTrace();
    		Log.d("ERROR in SearchAct", "URL Encoding error");
    	}
    }
    
    
    private void loadData_legacy() {
		hasNext = false;
		List<News> newItems = News.search(getReadableDatabase(), keyword, start, rows + 1);
		if (newItems != null && newItems.size() > 0) {
			if (newItems.size() == rows + 1) {
				newItems.remove(rows); // 다음페이지 유무를 위해 가져온 로우를 데이터에서 제외
				hasNext = true;
			}
			items.addAll(newItems);
		}
    }
    
	/**
	 * 다음 페이지 데이터 조회
	 */
    private void loadNextData() {
    	start += App.ROW_PER_PAGE;
    	this.page += 1;
    	new AsyncTask<String, Integer, Boolean>() {
    		private ProgressDialog progressDialog;
    		
    		@Override
    		protected void onPreExecute() {
    			super.onPreExecute();
    	    	progressDialog = ProgressDialog.show(
    	        		SearchAct.this, App.APP_TITLE, "글을 검색하고 있습니다.", true, false);
    		}
    		
			@Override
			protected Boolean doInBackground(String... params) {
				loadData();
//				loadData_legacy();
				return true;
			}
			
			@Override
			protected void onProgressUpdate(Integer... progress) {
			}

			@Override
			protected void onPostExecute(Boolean result) {
				((BaseAdapter)listView.getAdapter()).notifyDataSetChanged();
				progressDialog.dismiss();
			}

			@Override
			protected void onCancelled() {
				super.onCancelled();
				progressDialog.dismiss();
			}
		}.execute();
    }
    
	private class SearchAdapter extends BaseAdapter {
		private final static String TAG = "SearchAdapter";
	   	private final Activity context;

        public SearchAdapter(Activity context) {
        	this.context = context;
        }

        public int getCount() {
        	if (items == null)
        		return 0;
        	
        	return items.size() + (hasNext ? 1 : 0);
        }

        public Object getItem(int position) {
            return items.get(position);
        }

        public long getItemId(int position) {
            return position;
        }
        
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view = convertView;
            
            // 페이징
            if (items.size() == position) {
            	LayoutInflater vi = context.getLayoutInflater();
            	view = vi.inflate(R.layout.row_more_article, null);
            	ImageButton btn = (ImageButton)view.findViewById(R.id.row_more_btn);
            	btn.setOnClickListener(new OnClickListener() {
        			@Override
        			public void onClick(View v) {
        				loadNextData();
        			}
        		});
            	return view;
            }
            
            NewsResourceHolder holder = null;
            if (view == null || view.getTag() == null) {
            	LayoutInflater vi = context.getLayoutInflater();
//            	if (thumbDisplay)
//            		view = vi.inflate(R.layout.row_news_type2, null);
//            	else
            		view = vi.inflate(R.layout.row_news_type1, null);
                holder = new NewsResourceHolder(view);
                view.setTag(holder);
            } else {
            	holder = (NewsResourceHolder)view.getTag();
            }

            final News entry = items.get(position);
    		if (entry == null) {
    			return view;
    		}
    		
            if (holder.imageView != null) {
            	holder.imageView.setTag(position);
            	holder.imageView.setImageResource(App.RES_LOADING_110x75);
                new ImageReceiver(entry.thumb_default, (ImageReceivedCallback)context, 
                		holder.imageView, getThumbPath(), position);
                
                if (DebugFlag.isLogEnabled()) 
                	Log.d(TAG,
                		"pos="+position+
                		" img="+holder.imageView+
                		" cv="+convertView+
                		" par="+parent);
            }
            
            if (holder.titleView != null)
            	holder.titleView.setText(entry.title);
            
            if (holder.detailView != null) {
            int len = entry.body_text.length();
            	if (len > 256) len = 256;
            	holder.detailView.setText(entry.body_text.substring(0, len));
            }
            
            // set audio play button
            if (holder.button != null) {
            	holder.button.setFocusable(false);
            	holder.button.setOnClickListener(new OnClickListener() {
					
					@Override
					public void onClick(View v) {
						AudioPlayerDialogTool.showPlayOrAddDialog(SearchAct.this, entry);
					}
				});
            	
            	if (entry.mp3_url.trim().length() == 0) {
            		holder.button.setEnabled(false);
            	} else {
            		holder.button.setEnabled(true);
            	}
            }
    		
    		return view;
        }
	}
}
